home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HamCall (April 1991)
/
HAMCALL CD-ROM (Buckmaster)(April 1991).BIN
/
prgming
/
ctutor
/
chap04.txt
< prev
next >
Wrap
Text File
|
1990-10-14
|
30KB
|
703 lines
Chapter 4
ASSIGNMENT & LOGICAL COMPARES
Throughout this chapter, references are given to various
ranges of variables. Your compiler may use a different range
for some of the variables since the proposed ANSI standard
does not define specific limits for all data types. Consult
the documentation for your compiler for the exact range for
each of the variable types.
INTEGER ASSIGNMENT STATEMENTS
______________________________________________________________
Load the file INTASIGN.C and display it for ==============
an example of assignment statements. Three INTASIGN.C
variables are defined for use in the program ==============
and the rest of the program is merely a
series of illustrations of various assignments. The first two
lines of the assignment statements assign numerical values to
"a" and "b", and the next five lines illustrate the five basic
arithmetic functions and how to use them. The fifth is the
modulo operator and gives the remainder if the two variables
were divided. It can only be applied to "int" or "char" type
variables. Following these, there are two lines illustrating
how to combine some of the variables in some complex math
expressions. All of the above examples should require no
comment except to say that none of the equations are meant to
be particularly useful except as illustrations. The "char"
type variable will be defined in the description of the next
example program.
The expressions in lines 17 and 18 are perfectly acceptable
as given, but we will see later in this chapter that there is
another way to write these for more compact code.
VERY STRANGE LOOKING CODE
______________________________________________________________
This leaves us with the last two lines which may appear to you
as being very strange. The C compiler scans the assignment
statement from right to left, (which may seem a bit odd since
we do not read that way), resulting in a very useful
construct, namely the one given here. The compiler finds the
value 20, assigns it to "c", then continues to the left
finding that the latest result of a calculation should be
assigned to "b". Thinking that the latest calculation
resulted in a 20, it assigns it to "b" also, and continues the
leftward scan assigning the value 20 to "a" also. This is a
very useful construct when you are initializing a group of
variables. The last statement illustrates that it is possible
to actually do some calculations to arrive at the value which
4-1
Chapter 4 - Assignment & Logical Compares
will be assigned to all three variables. In fact, the
rightmost expression can contain variables, even "a", "b", &
"c".
The program has no output, so compiling and executing this
program will be very uninteresting. Since you have already
learned how to display some integer results using the "printf"
function, it would be to your advantage to add some output
statements to this program to see if the various statements
do what you think they should do.
DEFINITIONS FIRST THEN EXECUTABLE STATEMENTS
______________________________________________________________
This would be a good time for a preliminary definition of a
rule to be followed in C. The data definitions are always
given before any executable statements in any program block.
This is why the variables are defined first in this program
and in every C program. If you try to define a new variable
after executing some statements, your compiler will issue an
error.
ADDITIONAL DATA TYPES
______________________________________________________________
Loading and editing MORTYPES.C will ==============
illustrate how some additional data types can MORTYPES.C
be used. Once again we have defined a few ==============
integer type variables which you should be
fairly familiar with by now, but we have added two new types,
the "char", and the "float".
The "char" type of data is nearly the same as the integer
except that it can only be assigned numerical values between
-128 to 127 on most implementations of C, since it is stored
in only one byte of memory. The "char" type of data is
usually used for ASCII data, more commonly known as text. The
text you are reading was originally written on a computer with
a word processor that stored the words in the computer one
character per byte. In contrast, the integer data type is
stored in two bytes of computer memory on nearly all
microcomputers.
DATA TYPE MIXING
______________________________________________________________
It would be profitable at this time to discuss the way C
handles the two types "char" and "int". Most functions in C
that are designed to operate with integer type variables will
work equally well with character type variables because they
are a form of an integer variable. Those functions, when
4-2
Chapter 4 - Assignment & Logical Compares
called on to use a "char" type variable, will actually promote
the "char" data into integer data before using it. For this
reason, it is possible to mix "char" and "int" type variables
in nearly any way you desire. The compiler will not get
confused, but you might. It is good not to rely on this too
much, but to carefully use only the proper types of data where
they should be used.
The second new data type is the "float" type of data, commonly
called floating point data. This is a data type which usually
has a very large range, a large number of significant digits,
and a large number of computer words are required to store it.
The "float" data type has a decimal point associated with it
and has an allowable range of from 3.4E-38 to 3.4E+38 when
using most C compilers on microcomputers, and is composed of
about 7 significant digits.
HOW TO USE THE NEW DATA TYPES
______________________________________________________________
The first three lines of the program assign values to all nine
of the defined variables so we can manipulate some of the data
between the different types.
Since, as mentioned above, a "char" data type is in reality
an "integer" data type, no special considerations need be
taken to promote a "char" to an "int", and a "char" type data
field can be assigned to an "int" variable. When going the
other way, there is no standard, so you may simply get garbage
if the value of the integer variable is outside the range of
the "char" type variable. Most C compilers simply truncate
the most significant bits and use the 8 least significant
bits. It will translate correctly if the value is within the
range of -128 to 127.
The third line illustrates the simplicity of translating an
integer into a "float", simply assign it the new value and the
system will do the proper conversion. When going the other
way however, there is an added complication. Since there may
be a fractional part of the floating point number, the system
must decide what to do with it. By definition, it will
truncate it.
This program produces no output, and we haven't covered a way
to print out "char" and "float" type variables, so you can't
really get in to this program and play with the results, but
the next program will cover this for you.
Be sure to compile and run this program after you are sure you
understand it completely.
4-3
Chapter 4 - Assignment & Logical Compares
LOTS OF VARIABLE TYPES
______________________________________________________________
Load the file LOTTYPES.C and display it on ==============
your screen. This file contains nearly every LOTTYPES.C
standard simple data type available in the ==============
programming language C. There are other
types, but they are the compound types (ie - arrays and
structures) that we will cover in due time.
Observe the file. First we define a simple "int", followed
by a "long int" which has a range of -2147483648 to 2147483647
with most C compilers, and a "short int" which has a range
that is identical to that for the "int" variable, namely
-32768 to 32767. The "unsigned" is next and is defined as the
same size as the "int" but with no sign. The "unsigned" then
will cover a range of 0 to 65535. It should be pointed out
that when the "long", "short", or "unsigned" is desired, the
"int" is optional and is left out by most experienced
programmers. We have already covered the "char" and the
"float", which leaves only the "double". The "double" covers
a greater range than the "float" and has more significant
digits for more precise calculations. It also requires more
memory to store a value than the simple "float". The "double"
in most C compilers covers a range of 1.7E-308 to 1.7E+308.
Note that other compounding of types can be done such as "long
unsigned int", "unsigned char", etc. Check your documentation
for a complete list of variable types.
Another diversion is in order at this point. Your compiler
has no provisions for floating point math, but only double
floating point math. It will promote a "float" to a "double"
before doing calculations and therefore only one math library
will be needed. Of course, this is totally transparent to
you, so you don't need to worry about it. Because of this,
you may think that it would be best to simply define every
floating point variable as double, since they are promoted
before use in any calculations, but that may not be a good
idea. A "float" variable requires 4 bytes of storage and a
"double" requires 8 bytes of storage, so if you have a large
volume of floating point data to store, the "double" will
obviously require much more memory.
After defining the data types in the program under
consideration, a numerical value is assigned to each of the
defined variables in order to demonstrate the means of
outputting each to the monitor.
4-4
Chapter 4 - Assignment & Logical Compares
SOME LATE ADDITIONS
______________________________________________________________
As any programming language evolves, additional constructs are
added to fill some previously overlooked need. Two new
keywords have been added to C recently, and since they may not
be a part of your compiler, they are not illustrated in
example programs, but they will be discussed here. The two
new keywords are "const" and "volatile" and are used to tell
the compiler that variables of these types are constants and
cannot be changed by the program. A constant declared with
the const keyword declares a value that will never be changed
by either the program or the system itself. If volatile is
used, it declares a value that will never be changed by the
program but may be changed by some outside influence such as
a clock update pulse incrementing a volatile type stored
value. Since these constants can never have a value assigned
to them in the executable part of the program, they should
always be initialized.
Examples of use in declaring constants of these two types are
given as;
const int index1 = 2;
const index2 = 6;
volatile const int index3 = 12;
volatile index4 = -23;
As mentioned earlier in this chapter, the keyword "int" is
optional when used with these constant definitions
THE CONVERSION CHARACTERS
______________________________________________________________
Following is a list of some of the conversion characters and
the way they are used in the "printf" statement. A complete
list of all of the conversion characters should be included
with the documentation for your compiler.
d decimal notation
o octal notation
x hexadecimal notation
u unsigned notation
c character notation
s string notation
f floating point notation
Each of these is used following a percent sign to indicate the
type of output conversion, and between those two characters,
the following fields may be added.
4-5
Chapter 4 - Assignment & Logical Compares
- left justification in its field
(n) a number specifying minimum field width
. to separate n from m
(m) significant fractional digits for a float
l to indicate a "long"
These are all used in the examples which are included in the
program presently displayed on your monitor, with the
exception of the string notation which will be covered later
in this tutorial. Note especially the variable field width
specification demonstrated in lines 33 to 36. This is not
part of the original definition of C, but it is included in
the proposed ANSI standard and will become part of the C
language. Compile and run this program to see what effect the
various fields have on the output.
You now have the ability to display any of the data fields in
the previous programs and it would be to your advantage to go
back and see if you can display some of the fields anyway you
desire.
LOGICAL COMPARES
______________________________________________________________
Load and view the file named COMPARES.C for ==============
many examples of compare statements in C. We COMPARES.C
begin by defining and initializing nine ==============
variables to use in the following compare
statements. This initialization is new to you and can be used
to initialize variables while they are defined.
The first group of compare statements represents the simplest
kinds of compares since they simply compare two variables.
Either variable could be replaced with a constant and still
be a valid compare, but two variables is the general case.
The first compare checks to see if "x" is equal to "y" and it
uses the double equal sign for the comparison. A single equal
sign could be used here but it would have a different meaning
as we will see shortly. The second comparison checks to see
if "x" is greater than "z".
The third compare introduces the "NOT" operator, the
exclamation, which can be used to invert the result of any
logical compare. The fourth checks for "b" less than or equal
to "c", and the last checks for "r" not equal to "s". As we
learned in the last chapter, if the result of the compare is
true, the statement following the "if" clause will be executed
and the results are given in the comments.
Note that "less than" and "greater than or equal to" are also
available, but are not illustrated here.
4-6
Chapter 4 - Assignment & Logical Compares
It would be well to mention the different format used for the
"if" statement in this example program. A carriage return is
not required as a statement separator and by putting the
conditional clause on the same line as the "if", it adds to
the readability of the overall program.
MORE COMPARES
______________________________________________________________
The compares in the second group are a bit more involved.
Starting with the first compare, we find a rather strange
looking set of conditions in the parentheses. To understand
this we must understand just what a "true" or "false" is in
the C language. A "false" is defined as a value of zero, and
"true" is defined as a non-zero value. Any integer or char
type of variable can be used for the result of a true/false
test, or the result can be an implied integer or char.
Look at the first compare of the second group of compare
statements. The expression "r != s" will evaluate as a "true"
since "r" was set to 0.0 above, so the result will be a
non-zero value. With most C compilers, it would always be set
to a 1, but you could get in trouble if you wrote a program
that depended on it being 1 in all cases. Good programming
practice would be to not use the resulting 1 in any
calculations. Even though the two variables that are compared
are "float" variables, the result will be of type "integer".
There is no explicit variable to which it will be assigned so
the result of the compare is an implied integer. Finally the
resulting number, probably 1 in this case, is assigned to the
integer variable "x". If double equal signs were used, the
phantom value, namely 1, would be compared to the value of
"x", but since the single equal sign is used, the value 1 is
simply assigned to "x", as though the statement were not in
parentheses. Finally, since the result of the assignment in
the parentheses was non-zero, the entire expression is
evaluated as "true", and "z" is assigned the value of 1000.
Thus we accomplished two things in this statement, we assigned
"x" a new value, probably 1, and we assigned "z" the value of
1000. We covered a lot in this statement so you may wish to
review it before going on. The important things to remember
are the values that define "true" and "false", and the fact
that several things can be assigned in a conditional
statement. The value assigned to "x" was probably a 1, but
remember that the only requirement is that it is nonzero.
The next example should help clear up some of the above in
your mind. In this example, "x" is assigned the value of "y",
and since the result is 11, the condition is non-zero, which
is true, and the variable "z" is assigned 222.
The third example, in the second group, compares "x" to zero.
If the result is true, meaning that if "x" is not zero, then
4-7
Chapter 4 - Assignment & Logical Compares
"z" is assigned the value of 333, which it will be. The last
example in this group illustrates the same concept, since the
result will be true if "x" is non-zero. The compare to zero
is not actually needed and the result of the compare is true.
The third and fourth examples of this group are therefore
identical.
ADDITIONAL COMPARE CONCEPTS
______________________________________________________________
The third group of compares will introduce some additional
concepts, namely the logical "AND" and the logical "OR". We
assign the value of 77 to the three integer variables simply
to get started again with some defined values. The first
compare of the third group contains the new control "&&",
which is the logical "AND". The entire statement reads, if
"x" equals "y" AND if "x" equals 77 then the result is "true".
Since this is true, the variable z is set equal to 333.
The next compare in this group introduces the "||" operator
which is the "OR". The statement reads, if "x" is greater
than "y" OR if "z" is greater than 12 then the result is true.
Since "z" is greater than 12, it doesn't matter if "x" is
greater than "y" or not, because only one of the two
conditions must be true for the result to be true. The result
is true, so therefore "z" will be assigned the value of 22.
LOGICAL EVALUATION
______________________________________________________________
When a compound expression is evaluated, the evaluation
proceeds from left to right and as soon as the result of the
outcome is assured, evaluation stops. Namely, in the case of
an "AND" evaluation, when one of the terms evaluates to
"false", evaluation is discontinued because additional true
terms cannot make the result ever become "true". In the case
of an "OR" evaluation, if any of the terms is found to be
"true", evaluation stops because it will be impossible for
additional terms to cause the result to be "false". In the
case of additionally nested terms, the above rules will be
applied to each of the nested levels.
PRECEDENCE OF OPERATORS
______________________________________________________________
The question will come up concerning the precedence of
operators. Which operators are evaluated first and which
last? There are many rules about this topic, but I would
suggest that you don't worry about it at this point. Instead,
use lots of parentheses to group variables, constants, and
operators in a way meaningful to you. Parentheses always have
4-8
Chapter 4 - Assignment & Logical Compares
the highest priority and will remove any question of which
operations will be done first in any particular statements.
Going on to the next example in group three, we find three
simple variables used in the conditional part of the compare.
Since all three are non-zero, all three are "true", and
therefore the "AND" of the three variables are true, leading
to the result being "true", and "z" being assigned the value
of 11. Note that since the variables, "r", "s", and "t" are
"float" type variables, they could not be used this way, but
they could each be compared to zero and the same type of
expression could be used.
Continuing on to the fourth example of the third group we find
three assignment statements in the compare part of the "if"
statement. If you understood the above discussion, you should
have no difficulty understanding that the three variables are
assigned their respective new values, and the result of all
three are non-zero, leading to a resulting value of "TRUE".
THIS IS A TRICK, BE CAREFUL
______________________________________________________________
The last example of the third group contains a bit of a trick,
but since we have covered it above, it is nothing new to you.
Notice that the first part of the compare evaluates to
"FALSE". The remaining parts of the compare are not
evaluated, because it is an "AND" and it will definitely be
resolved as a "FALSE" because the first term is false. If the
program was dependent on the value of "y" being set to 3 in
the next part of the compare, it will fail because evaluation
will cease following the "FALSE" found in the first term.
Likewise, "z" will not be set to 4, and the variable "r" will
not be changed.
POTENTIAL PROBLEM AREAS
______________________________________________________________
The last group of compares illustrate three possibilities for
getting into a bit of trouble. All three have the common
result that "z" will not get set to the desired value, but for
different reasons. In the case of the first one, the compare
evaluates as "true", but the semicolon following the second
parentheses terminates the "if" clause, and the assignment
statement involving "z" is always executed as the next
statement. The "if" therefore has no effect because of the
misplaced semicolon. The second statement is much more
straightforward because "x" will always be equal to itself,
therefore the inequality will never be true, and the entire
statement will never do a thing, but is wasted effort. The
last statement will always assign 0 to "x" and the compare
4-9
Chapter 4 - Assignment & Logical Compares
will therefore always be "false", never executing the
conditional part of the "if" statement.
The conditional statement is extremely important and must be
thoroughly understood to write efficient C programs. If any
part of this discussion is unclear in your mind, restudy it
until you are confident that you understand it thoroughly
before proceeding onward. Compile and run this program. Add
some printout to see the results of some of the operations.
THE CRYPTIC PART OF C
______________________________________________________________
There are three constructs used in C that =============
make no sense at all when first encountered CRYPTIC.C
because they are not intuitive, but they =============
greatly increase the efficiency of the
compiled code and are used extensively by experienced C
programmers. You should therefore be exposed to them and
learn to use them because they will appear in most, if not
all, of the programs you see in the publications. Load and
examine the file named CRYPTIC.C for examples of the three new
constructs.
In this program, some variables are defined and initialized
in the same statements for use below. The first executable
statement simply adds 1 to the value of "x", and should come
as no surprise to you. The next two statements also add one
to the value of "x", but it is not intuitive that this is what
happens. It is simply by definition that this is true.
Therefore, by definition of the C language, a double plus sign
either before or after a variable increments that variable by
1. Additionally, if the plus signs are before the variable,
the variable is incremented before it is used, and if the
plus signs are after the variable, the variable is used, then
incremented. In the next statement, the value of "y" is
assigned to the variable "z", then "y" is incremented because
the plus signs are after the variable "y". In the last
statement of the incrementing group of example statements, the
value of "y" is incremented then its value is assigned to the
variable "z".
The next group of statements illustrate decrementing a
variable by one. The definition works exactly the same way
for decrementing as it does for incrementing. If the minus
signs are before the variable, the variable is decremented,
then used, and if the minus signs are after the variable, the
variable is used, then decremented.
4-10
Chapter 4 - Assignment & Logical Compares
THE CRYPTIC ARITHMETIC OPERATOR
______________________________________________________________
Another useful but cryptic operator is the arithmetic
operator. This operator is used to modify any variable by
some constant value. The first statement of the "arithmetic
operator" group of statements simply adds 12 to the value of
the variable "a". The second statement does the same, but
once again, it is not intuitive that they are the same. Any
of the four basic functions of arithmetic, "+", "-", "*", or
"/", can be handled in this way, by putting the function
desired in front of the equal sign and eliminating the second
reference to the variable name. It should be noted that the
expression on the right side of the arithmetic operator can
be any valid expression, the examples are kept simple for your
introduction to this new operator.
Just like the incrementing and decrementing operators, the
arithmetic operator is used extensively by experienced C
programmers and it would pay you well to understand it.
THE CONDITIONAL EXPRESSION
______________________________________________________________
The conditional expression is just as cryptic as the last two,
but once again it can be very useful so it would pay you to
understand it. It consists of three expressions within
parentheses separated by a question mark and a colon. The
expression prior to the question mark is evaluated to
determine if it is "true" or "false". If it is true, the
expression between the question mark and the colon is
evaluated, and if it is not true, the expression following the
colon is evaluated. The result of the evaluation is used for
the assignment. The final result is identical to that of an
"if" statement with an "else" clause. This is illustrated by
the second example in this group. The conditional expression
has the added advantage of more compact code that will compile
to fewer machine instructions in the final program.
The final two lines of this example program are given to
illustrate a very compact way to assign the greater of two
variables "a" or "b" to "c", and to assign the lessor of the
same two variables to "c". Notice how efficient the code is
in these two examples.
TO BE CRYPTIC OR NOT TO BE CRYPTIC
______________________________________________________________
Several students of C have stated that they didn't like these
three cryptic constructs and that they would simply never use
them. This will be fine if they never have to read anybody
else's program, or use any other programs within their own.
4-11
Chapter 4 - Assignment & Logical Compares
I have found many functions that I wished to use within a
program but needed a small modification to use it, requiring
me to understand another person's code. It would therefore
be to your advantage to learn these new constructs, and use
them. They will be used in the remainder of this tutorial, so
you will be constantly exposed to them.
This has been a long chapter but it contained important
material to get you started in using C. In the next chapter,
we will go on to the building blocks of C, the functions. At
that point, you will have enough of the basic materials to
allow you to begin writing meaningful programs.
PROGRAMMING EXERCISES
______________________________________________________________
1. Write a program that will count from 1 to 12 and print
the count, and its square, for each count.
1 1
2 4
3 9 etc.
2. Write a program that counts from 1 to 12 and prints the
count and its inversion to 5 decimal places for each
count. This will require a floating point number.
1 1.00000
2 .50000
3 .33333
4 .25000
etc.
3. Write a program that will count from 1 to 100 and print
only those values between 32 and 39, one to a line.
4-12